from fastapi import APIRouter, Depends
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.sql import exists, select

from utils.db import get_session
from utils.jwt_utils import create_jwt_token
from utils.response import UserIsExistResponse, SuccessResponse, DatabaseErrorResponse, UserIsNotExistResponse, \
    AccountOrPasswordIsIncorrectResponse
from .forms import RegisterForm, LoginForm
from .models import UserModel

router = APIRouter(prefix="/user")


@router.get("/")
async def index():
    return DatabaseErrorResponse()


@router.post("/login")
async def login(form: LoginForm, db_session: AsyncSession = Depends(get_session)):
    """
    登录函数
    :param form: 表单参数
    :param db_session: 数据库会话
    :return:
    """
    # 开启事务
    async with db_session.begin():
        try:
            # 创建sql 获取用户对象
            sql = select(UserModel).where(UserModel.name == form.username)
            # 执行语句
            obj = (await db_session.execute(sql)).scalar()
            # 判断用户是否存在
            if obj is None:
                return UserIsNotExistResponse()
            # 判断密码是否正确
            if not obj.verify_password(form.password, obj.password):
                return AccountOrPasswordIsIncorrectResponse()
            # 创建jwt token
            jwt_token = create_jwt_token(obj.to_dict())
            # 返回成功
            return SuccessResponse(data=jwt_token)
        except SQLAlchemyError:
            return DatabaseErrorResponse()


@router.post("/register")
async def register(form: RegisterForm, db_session: AsyncSession = Depends(get_session)):
    """
    注册函数
    :param form: 表单参数
    :param db_session: 数据库会话
    :return:
    """
    # 开启事务
    async with db_session.begin():
        try:
            # 创建sql 判断用户是否存在
            sql = exists(UserModel).where(UserModel.name == form.username).select()
            # 执行sql语句
            item = (await db_session.execute(sql)).scalar()
            # 如果用户已存在
            if item:
                return UserIsExistResponse()
            # 创建用户模型对象
            obj = UserModel()
            obj.name = form.username
            obj.password = UserModel.get_password_hash(form.password)
            # 添加到会话
            db_session.add(obj)
            # 提交
            await db_session.commit()
            # 返回成功
            return SuccessResponse()
        except SQLAlchemyError:
            # 回滚
            await db_session.rollback()
            # 返回数据库错误
            return DatabaseErrorResponse()
